Integration and Connectivity
Table of content
1. Overview
This chapter aims to give a comprehensive description of all openMSP430
core interfaces in order to facilitate its integration within an ASIC
or FPGA.
The
following diagram shows an overview of the openMSP430 core connectivity
in an FPGA system (i.e. all ASIC specific pins are left unused):
The full pinout of the core is summarized in the following table.
Port Name | Direction | Width | Clock
Domain
|
Description |
Clocks |
cpu_en |
Input |
1 |
or mclk4 |
Enable CPU code execution (asynchronous and non-glitchy). Set to 1 if unused. |
dco_clk |
Input |
1 |
-
|
Fast oscillator (fast clock) |
lfxt_clk |
Input |
1 |
-
|
Low frequency oscillator (typ. 32kHz) Set to 0 if unused. |
mclk |
Output |
1 |
-
|
Main system clock |
aclk_en |
Output |
1 |
mclk
|
FPGA ONLY: ACLK enable |
smclk_en |
Output |
1 |
mclk
|
FPGA ONLY: SMCLK enable |
dco_enable |
Output
|
1
|
dco_clk
|
ASIC ONLY: Fast oscillator enable |
dco_wkup |
Output |
1
|
|
ASIC ONLY: Fast oscillator wakeup (asynchronous) |
lfxt_enable |
Output |
1
|
lfxt_clk
|
ASIC ONLY: Low frequency oscillator enable |
lfxt_wkup |
Output |
1
|
|
ASIC ONLY: Low frequency oscillator wakeup (asynchronous) |
aclk |
Output |
1
|
-
|
ASIC ONLY: ACLK |
smclk |
Output |
1
|
-
|
ASIC ONLY: SMCLK |
wkup |
Input
|
1
|
|
ASIC ONLY: System Wake-up (asynchronous and non-glitchy) Set to 0 if unused. |
Resets |
puc_rst |
Output |
1 |
mclk
|
Main system reset |
reset_n |
Input |
1 |
|
Reset Pin (active low, asynchronous and non-glitchy) |
Program Memory interface |
pmem_addr |
Output |
`PMEM_AWIDTH1 |
mclk
|
Program Memory address |
pmem_cen |
Output |
1 |
mclk |
Program Memory chip enable (low active) |
pmem_din |
Output |
16 |
mclk |
Program Memory data input (optional 2) |
pmem_dout |
Input |
16 |
mclk |
Program Memory data output |
pmem_wen |
Output |
2 |
mclk |
Program Memory write byte enable (low active) (optional 2) |
Data Memory interface |
dmem_addr |
Output |
`DMEM_AWIDTH1 |
mclk |
Data Memory address |
dmem_cen |
Output |
1 |
mclk |
Data Memory chip enable (low active) |
dmem_din |
Output |
16 |
mclk |
Data Memory data input |
dmem_dout |
Input |
16 |
mclk |
Data Memory data output |
dmem_wen |
Output |
2 |
mclk |
Data Memory write byte enable (low active) |
External Peripherals interface |
per_addr |
Output |
14 |
mclk |
Peripheral address |
per_din |
Output |
16 |
mclk |
Peripheral data input |
per_dout |
Input |
16 |
mclk |
Peripheral data output |
per_en |
Output |
1 |
mclk |
Peripheral enable (high active) |
per_we |
Output |
2 |
mclk |
Peripheral write byte enable (high active) |
Direct Memory Access interface |
dma_addr |
Input |
15 |
mclk
|
Direct Memory Access address |
dma_din |
Input |
16 |
mclk
|
Direct Memory Access data input |
dma_dout |
Output |
16 |
mclk
|
Direct Memory Access data output |
dma_en |
Input |
1 |
mclk
|
Direct Memory Access enable (high active) |
dma_priority |
Input |
1 |
mclk
|
Direct Memory Access priority (0:low / 1:high) |
dma_ready |
Output |
1 |
mclk
|
Direct Memory Access is complete |
dma_resp |
Output |
1 |
mclk
|
Direct Memory Access response (0:Okay / 1:Error) |
dma_we |
Input |
2 |
mclk
|
Direct Memory Access write byte enable (high active) |
dma_wkup |
Input |
1 |
|
ASIC ONLY: DMA Wake-up (asynchronous and non-glitchy) |
Interrupts |
irq |
Input |
`IRQ_NR-21 |
mclk |
Maskable interrupts (one-hot signal) |
nmi |
Input |
1 |
or mclk4 |
Non-maskable interrupt (asynchronous) |
irq_acc |
Output |
`IRQ_NR-21 |
mclk |
Interrupt request accepted (one-hot signal) |
Serial Debug interface |
dbg_en |
Input |
1 |
or mclk4 |
Debug interface enable (asynchronous) 3 |
dbg_freeze |
Output |
1 |
mclk |
Freeze peripherals |
dbg_uart_txd |
Output |
1 |
mclk |
Debug interface: UART TXD |
dbg_uart_rxd |
Input |
1 |
|
Debug interface: UART RXD (asynchronous) |
dbg_i2c_addr |
Input |
1 |
mclk
|
Debug interface: I2C Address |
dbg_i2c_broadcast |
Input |
1 |
mclk
|
Debug interface: I2C Broadcast Address (for multicore only) |
dbg_i2c_scl |
Input |
1 |
|
Debug interface: I2C SCL |
dbg_i2c_sda_in |
Input |
1 |
|
Debug interface: I2C SDA input |
dbg_i2c_sda_out |
Output |
1 |
mclk
|
Debug interface: I2C SDA output |
Scan |
scan_enable
|
Input
|
1
|
dco_clk
|
ASIC ONLY: Scan enable (active during scan shifting) |
scan_mode
|
Input
|
1
|
|
ASIC ONLY: Scan mode |
1: This parameter is declared in the "openMSP430_defines.v" file and defines the RAM/ROM size or the number of interrupts vectors (16, 32 or 64).
2:
These two optional ports can be connected whenever the program memory
is a RAM. This will allow the user to load a program through the serial
debug interface and to use software breakpoints.
3: When disabled, the debug interface is hold into reset (and clock gated in ASIC mode). As a consequence, the dbg_en port can be used to reset the debug interface without disrupting the CPU execution.
4: Clock domain is selectable through configuration in the "openMSP430_defines.v" file (see Advanced System Configuration).
2. Clocks
The different clocks in the design are managed by the Basic Clock Module as following in the FPGA configuration:
or as following in the ASIC configuration:
-
CPU_EN: this input port provides a hardware mean to stop or resume CPU execution. When unused, this port should be set to 1.
-
DCO_CLK: this input port is typically connected to a PLL, RC oscillator or any clock resource the target FPGA/ASIC might provide.
For the FPGA configuration, from a synthesis tool perspective (ISE, Quartus, Libero, Design
Compiler...), this the only port where a clock needs to be declared.
-
LFXT_CLK:
in an FPGA system, if ACLK_EN or SMCLK_EN are going to be used in the project (for example
through the Watchdog or TimerA peripherals), then this port needs to be
connected to a clock running at least two time slower as DCO_CLK
(typically 32kHz). It can be connected to 0 or 1 otherwise.
In an ASIC, if ACLK or SMCLK are used and if the clock muxes are
included, then this port can be connected to any kind of clock source
(it doesn't need to be low-frequency. The name was just
kept to be consistent with TI's documentation).
-
MCLK:
the main system clock drives the complete openMSP430 clock domain,
including program/data memories and the peripheral interfaces.
-
ACLK_EN / SMCLK_EN:
these two clock enable signals can be used in order to emulate the
original ACLK and SMCLK from the MSP430 specification when the core is
targeting an FPGA.
An example of this can be found in the Watchdog and TimerA modules, where it is implemented as following:
-
ACLK / SMCLK: ACLK and MCLK are available through these two ports when targeting an ASIC.
-
DCO_ENABLE / DCO_WKUP: ASIC specific signals controlling the fast clock generator for low power mode support (SCG0 bit in the status register).
-
LFXT_ENABLE / LFXT_WKUP:
ASIC specific signals controlling the low frequency clock generator for
low power mode support (OSCOFF bit in the status register).
- WKUP:
When activated, this signal allows a peripheral to restore all CPU
clocks (i.e. wakeup the cpu) prior IRQ generation. Note that IRQs
MUST always be generated from the MCLK clock domain.
As an FPGA system illustration, the following waveform shows the different
clocks where the software running on the openMSP430 configures the
BCSCTL1 and BCSCTL2 registers so that
ACLK_EN and
SMCLK_EN are respectively running at
LFXT_CLK/2 and
DCO_CLK/4.
3. Resets
- RESET_N: this input port is typically connected to a board push button and is generally combined with the system power-on-reset.
-
PUC_RST: the Power-Up-Clear signal is asynchronously set with the reset pin (RESET_N),
the watchdog reset or the serial debug interface reset. In order to get
clean timings, it is synchronously cleared with MCLK. As
a general rule, this signal should be used as the reset of the MCLK clock domain.
The following waveform illustrates this:
4. Program Memory
Depending on the project needs, the program memory can be either implemented as a ROM or RAM.
If a ROM is selected then the
PMEM_DIN and
PMEM_WEN
ports won't be connected. In that case, the software debug capabilities
are limited because the serial debug interface can only use hardware
breakpoints in order to stop the program execution. In addition,
updating the software will require a reprogramming of the FPGA... or a new ROM mask for an ASIC.
If the program memory is a RAM, the developer gets full flexibility
regarding software debugging. The serial debug interface can be used to
update the program memory and software breakpoints can be used.
That said, the protocol between the openMSP430 and the program memory is quite standard. Signal description goes as following:
- PMEM_CEN: when this signal is active, the read/write access will be executed with the next MCLK rising edge. Note that this signal is LOW ACTIVE.
-
PMEM_ADDR: Memory address of the 16 bit word which is going to be accessed.
Note: in order to calculate the core logical address from the program memory physical address, the formula goes as following: LOGICAL@=2*PHYSICAL@+0x10000-PMEM_SIZE
-
PMEM_DOUT: the memory output word will be updated with every valid read/write access (i.e. PMEM_DOUT is not updated if PMEM_CEN=1).
-
PMEM_WEN:
this signal selects which byte should be written during a valid access.
PMEM_WEN[0] will activate a write on the lower byte, PMEM_WEN[1] a
write on the upper byte. Note that these signals are LOW ACTIVE.
-
PMEM_DIN: the memory input word will be written with the valid write access according to the PMEM_WEN value.
The following waveform illustrates some read accesses of the program
memory (write access are illustrated in the data memory section):
5. Data Memory
The data memory is always implemented as a RAM.
The protocol between the openMSP430 and the data memory is the same as
the one of the program memory. Therefore, the signal description is the
same:
- DMEM_CEN: when this signal is active, the read/write access will be executed with the next MCLK rising edge. Note that this signal is LOW ACTIVE.
-
DMEM_ADDR: Memory address of the 16 bit word which is going to be accessed.
Note: in order to calculate the core logical address from the data memory physical address, the formula goes as following: LOGICAL@=2*PHYSICAL@+0x200
-
DMEM_DOUT: the memory output word will be updated with every valid read/write access (i.e. DMEM_DOUT is not updated if DMEM_CEN=1).
-
DMEM_WEN:
this signal selects which byte should be written during a valid access.
DMEM_WEN[0] will activate a write on the lower byte, DMEM_WEN[1] a
write on the upper byte. Note that these signals are LOW ACTIVE.
-
DMEM_DIN: the memory input word will be written with the valid write access according to the DMEM_WEN value.
The following waveform illustrates some read/write access to the data memory:
6. Peripherals
The protocol between the openMSP430 core and its peripherals is the
exactly same as the one with the data and program memories in regard
to write access and differs slightly for read access.
On the connectivity side, the specificity is that the read data bus of
all peripherals should be ORed together before being connected to the
core, as showed in the diagram of the
Overview section.
From the logical point of view, during a read access, each peripheral
outputs the combinatorial value of its read mux and returns 0 if it
doesn't contain the addressed register. On the waveforms, this
translates by seeing the register value on
PER_DOUT while
PER_EN is valid and not one clock cycle afterward as it is the case with the program and data memories.
In any case, it is recommended to use the templates provided with the core in order to develop your own custom peripherals.
The signal description therefore goes as following:
- PER_EN: when this signal is active, read access are executed during the current MCLK cycle while write access will be executed with the next MCLK rising edge. Note that this signal is HIGH ACTIVE.
-
PER_ADDR:
peripheral register address of the 16 bit word which is currently
accessed. It is to be noted that a 14 bit address will always be
provided from the openMSP430 to the peripheral in order to accommodate
the biggest possible PER_SIZE Verilog configuration option (i.e. 32kB
as opposed to 512B by default).
Note: in order to calculate the core logical address from the peripheral register physical address, the formula goes as following: LOGICAL@=2*PHYSICAL@
-
PER_DOUT: the peripheral output word will be updated with every valid read/write access, it will be set to 0 otherwise.
-
PER_WE:
this signal selects which byte should be written during a valid access.
PER_WE[0] will activate a write on the lower byte, PER_WE[1] a write on
the upper byte. Note that these signals are HIGH ACTIVE.
-
PER_DIN: the peripheral input word will be written with the valid write access according to the PER_WE value.
The following waveform illustrates some read/write access to the peripheral registers:
7. Direct Memory Access Interface
Before moving on, please note that further details about the DMA interface can
be found in its
dedicated section.
The protocol between the DMA interface master (DMA controller, bootloader, ...) and the openMSP430 core is similar
to the one followed between the openMSP430 and its data memory.
However, it comes with a few additional features to support wait states, error response, priority and wakeup (for LPMx modes).
The signal description goes as following:
- DMA_EN:
this signal enables a DMA transfer and can be released once the transfer is completed, as signaled by DMA_READY.
-
DMA_ADDR:
Logical address of the 16bit word currently accessed by the interface. The address must stay valid until the transfer is completed, as signaled by DMA_READY.
Note: the integrated oMSP memory backbone module decode the specified logical DMA address and maps it accordingly to the physical address of the Program, Data or Peripheral memory.
-
DMA_DOUT:
When performing a read acces, the DMA data output is valid during the MCLK cycle immediately following the end of the transfer, as signaled by DMA_READY.
-
DMA_WE:
This signal, asserted together with DMA_EN, allows to selects which byte should be written during the transfer.
DMA_WE[0] activates a write on the lower byte, DMA_WE[1] a write on the upper byte.
-
DMA_DIN:
When performing a write access, the DMA data input must stay valid until the transfer is completed, as signaled by DMA ready.
-
DMA_PRIORITY:
When SET, the oMSP memory backbone gives highest priority to the DMA transfer and stops CPU execution.
When CLEARED, the oMSP memory backbone gives highest priority to CPU execution and the DMA transfer is completed only when the CPU doesn't access the targeted ressource (pmem, dmem or peripheral).
Note: a DMA controller can control the DMA data rate without stalling the CPU by dynamically asserting/deasserting the DMA_PRIORITY port between transfers.
-
DMA_READY:
This port signals that the current DMA transfer is completed.
Note: DMA_READY is typically hold low when the CPU owns the interface of the target ressource.
-
DMA_RESP:
This port signals if the current transfer was successful (0) or if an error occured (1) and is valid together with DMA_READY.
Note: an error is typically signaled when an access is performed outside of any memory mapped area (for example between Program and Data memory).
-
DMA_WKUP:
For ASIC implementations supporting the Low-Power-Modes, this port is used to asynchronously restore the clocks before performing a DMA transfer.
Note: it is possible to control which clocks are restored during a DMA wakeup using the BCSCTL1 register of the Basic Clock Module.
The following waveform illustrates some read/write access using the DMA interface:
8. Interrupts
As with the original MSP430, the interrupt
priorities of the openMSP430 are fixed in hardware accordingly to the
connectivity of the
NMI and
IRQ ports.
If two interrupts are pending simultaneously, the higher priority interrupt will be serviced first.
The following table summarize this:
Interrupt Port |
Vector address |
Priority |
RESET_N |
0xFFFE |
15 (highest) |
NMI |
0xFFFC |
14 |
IRQ[13] |
0xFFFA |
13 |
IRQ[12] |
0xFFF8 |
12 |
IRQ[11] |
0xFFF6 |
11 |
IRQ[10] |
0xFFF4 |
10 |
IRQ[9] |
0xFFF2 |
9 |
IRQ[8] |
0xFFF0 |
8 |
IRQ[7] |
0xFFEE |
7 |
IRQ[6] |
0xFFEC |
6 |
IRQ[5] |
0xFFEA |
5 |
IRQ[4] |
0xFFE8 |
4 |
IRQ[3] |
0xFFE6 |
3 |
IRQ[2] |
0xFFE4 |
2 |
IRQ[1] |
0xFFE2 |
1 |
IRQ[0] |
0xFFE0 |
0 (lowest) |
The signal description goes as following:
-
NMI: The Non-Maskable Interrupt has higher priority than other IRQs and is masked by the NMIIE bit instead of GIE.
It is internally synchronized to the MCLK
domain and can therefore be connected to any asynchronous signal of the
chip (which could for example be a pin of the FPGA). If unused, this
signal should be connected to 0.
-
IRQ: The standard interrupts can be connected to any signal coming from the MCLK domain (typically a peripheral). Priorities can be chosen by selecting the proper bit of the IRQ bus as shown in the table above. Unused interrupts should be connected to 0.
Note: IRQ[10] is internally connected to the Watchdog
interrupt. If this bit is also used by an external peripheral, they
will both share the same interrupt vector.
-
IRQ_ACC:
Whenever an interrupt request is serviced, some peripheral
automatically clear their pending flag in hardware. In order to do so,
the IRQ_ACC bus can be used by using the bit matching the corresponding IRQ bit. An example of this is shown in the implementation of the TACCR0 Timer A interrupt.
The following waveform illustrates a TAIV interrupt issued by the Timer-A, which is connected to
IRQ[8] :
9. Serial Debug Interface
The serial debug interface module provides a two-wires communication
bus (UART or I2C) for remote debugging and an additional freeze signal which might be
useful for some peripherals (typically timers).
-
DBG_EN: this signal
allows the user to enable or disable the serial debug interface without
interfering with the CPU execution. It is to be noted that when
disabled (i.e. DBG_EN=0), the debug interface is held into reset.
-
DBG_FREEZE: this signal will be set whenever the debug interface stops the CPU (and if the FRZ_BRK_EN field of the CPU_CTL debug register is set). As its name implies, the purpose of DBG_FREEZE is to freeze a peripheral whenever the CPU is stopped by the software debugger.
For example, it is used by the Watchdog timer in order to stop its
free-running counter. This prevents the CPU from being reseted by the
watchdog every times the user stops the CPU during a debugging session.
9.1 UART Configuration
-
DBG_UART_TXD / DBG_UART_RXD: these signals are typically connected to an RS-232 transceiver and will allow a PC to communicate with the openMSP430 core.
The following waveform shows some communication traffic on the UART serial bus :
9.2 I2C Configuration
-
DBG_I2C_ADDR: I2C Device address of the oMSP core (between 8 and 119). In a multi-core configuration each core has its own address.
-
DBG_I2C_BROADCAST:
I2C Device broadcast address of the oMSP core (between 8 and 119). In a
multi-core configuration all cores have the same broadcast address.
-
DBG_I2C_SCL: I2C bus clock input (SCL).
-
DBG_I2C_SDA_OUT / DBG_I2C_SDA_IN: these signals are connected to the SDA I/O cell as following:
The following waveform shows some communication traffic on the I2C serial bus :